package com.yhsoft.sys.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhsoft.benefitcard.mapper.CardsBatch1Mapper;
import com.yhsoft.bill.entity.SysYszk;
import com.yhsoft.bill.mapper.SysYszkMapper;
import com.yhsoft.buyer.entity.BuyerOrder;
import com.yhsoft.buyer.entity.BuyerUser;
import com.yhsoft.buyer.mapper.BuyerOrderMapper;
import com.yhsoft.buyer.mapper.BuyerUserMapper;
import com.yhsoft.common.service.Po.TokenUser;
import com.yhsoft.common.service.TokenService;
import com.yhsoft.goods.entity.CompanyGoods;
import com.yhsoft.goods.entity.GoodsInfo;
import com.yhsoft.goods.mapper.CompanyGoodsMapper;
import com.yhsoft.goods.mapper.GoodsInfoMapper;
import com.yhsoft.sys.controller.Response.CompanyCountOutVo;
import com.yhsoft.sys.controller.Response.CompanySearchOutVo;
import com.yhsoft.sys.controller.Response.SystemSearchOutVo;
import com.yhsoft.sys.controller.request.DistributorInVo;
import com.yhsoft.sys.controller.request.SystemSearchInVo;
import com.yhsoft.sys.controller.request.VenderInVo;
import com.yhsoft.sys.entity.CompanyInfo;
import com.yhsoft.sys.entity.WorkOrderInfo;
import com.yhsoft.sys.mapper.CompanyInfoMapper;
import com.yhsoft.sys.mapper.WorkOrderInfoMapper;
import com.yhsoft.sys.service.ICompanyInfoService;
import com.yhsoft.sys.service.IWorkOrderInfoService;
import org.apache.ibatis.type.YearTypeHandler;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 公司信息表 服务实现类
 * </p>
 *
 * @author yyyyyyyh
 * @since 2023-09-23
 */
@Service
public class CompanyInfoServiceImpl extends ServiceImpl<CompanyInfoMapper, CompanyInfo> implements ICompanyInfoService {

    @Resource
    private BuyerOrderMapper buyerOrderMapper;

    @Resource
    private WorkOrderInfoMapper workOrderInfoMapper;

    @Resource
    private SysYszkMapper sysYszkMapper;

    @Resource
    private BuyerUserMapper buyerUserMapper;

    @Resource
    private CardsBatch1Mapper cardsBatch1Mapper;

    @Resource
    private CompanyGoodsMapper companyGoodsMapper;

    @Resource
    private CompanyInfoMapper companyInfoMapper;

    @Resource
    private GoodsInfoMapper goodsInfoMapper;

    @Override
    @Transactional
    public void addOrUpdateCompanyInfo(DistributorInVo distributorInVo) {
        CompanyInfo companyInfo = new CompanyInfo();
        BeanUtils.copyProperties(distributorInVo, companyInfo);
        companyInfo.setIsVendor(null);
        companyInfo.setIsDistributor(1);
        companyInfo.setIsOnlineVendor(null);
        TokenUser user = TokenService.getUserBytoken();
        // 判断是否有ID，有的话更新
        if (distributorInVo.getId() == null) {
            companyInfo.setCompanyStatus(1);
            companyInfo.setCreatedBy(user.getId());
            this.baseMapper.insert(companyInfo);
        } else {
            companyInfo.setUpdatedBy(user.getId());
            companyInfo.setId(distributorInVo.getId());
            this.baseMapper.updateById(companyInfo);
        }

    }

    @Override
    public void deleteDistributor(String ids) {
        String[] items = ids.split(",");
        List<Integer> IdList = Stream.of(items).map(Integer::parseInt).collect(Collectors.toList());
        this.baseMapper.deleteBatchIds(IdList);
    }

    @Override
    public void setDistributorStatus(Integer id) {
        CompanyInfo companyInfo = this.baseMapper.selectById(id);
        if (companyInfo.getCompanyStatus() != null && companyInfo.getCompanyStatus() == 1) {
            companyInfo.setCompanyStatus(0);
        } else {
            companyInfo.setCompanyStatus(1);
        }
        this.baseMapper.updateById(companyInfo);
    }

    @Override
    public void setVender(VenderInVo distributorInVo) {
        CompanyInfo companyInfo = new CompanyInfo();
        BeanUtils.copyProperties(distributorInVo, companyInfo);
        companyInfo.setIsVendor(1);
        companyInfo.setIsDistributor(null);
        companyInfo.setIsOnlineVendor(null);
        TokenUser user = TokenService.getUserBytoken();
        // 判断是否有ID，有的话更新
        if (distributorInVo.getId() == null) {
            companyInfo.setCompanyStatus(1);
            companyInfo.setCreatedBy(user.getId());
            this.baseMapper.insert(companyInfo);
        } else {
            companyInfo.setUpdatedBy(user.getId());
            companyInfo.setId(distributorInVo.getId());
            this.baseMapper.updateById(companyInfo);
        }

    }

    @Override
    public CompanySearchOutVo search() {
        Integer companyId = TokenService.getUserBytoken().getCompanyId();

        // 1.1 当前登录用户的统计信息
        LambdaQueryWrapper<CompanyInfo> qw = Wrappers.<CompanyInfo>lambdaQuery()
                .eq(CompanyInfo::getId, companyId);
        CompanyInfo companyInfo = this.baseMapper.selectOne(qw);
        CompanySearchOutVo companySearchOutVo = new CompanySearchOutVo();
        BeanUtils.copyProperties(companyInfo, companySearchOutVo);

        // 1.2 获取当前用户的待发货订单
        LambdaQueryWrapper<BuyerOrder> wrapper = Wrappers.<BuyerOrder>lambdaQuery()
                .eq(BuyerOrder::getOrderStatus, 2);
        Long awaitingDispatchNum = 0L;
        if (TokenService.getUserBytoken().getSysType().equals("vender")){
            awaitingDispatchNum = buyerOrderMapper.selectCount(wrapper.eq(BuyerOrder::getVendorId,companyId));
        }
        if (TokenService.getUserBytoken().getSysType().equals("saler")){
            awaitingDispatchNum = buyerOrderMapper.selectCount(wrapper.eq(BuyerOrder::getDistributorId,companyId));
        }
        companySearchOutVo.setAwaitingDispatchNum(awaitingDispatchNum);

        // 1.3 待处理工单
        Long awaitingProcessingNum = workOrderInfoMapper.selectCount(Wrappers.<WorkOrderInfo>lambdaQuery()
                .eq(WorkOrderInfo::getDistributorId, companyId)
                .eq(WorkOrderInfo::getProgress, 0));
        companySearchOutVo.setAwaitingProcessingNum(awaitingProcessingNum);

        // 1.4 预存款余额 = 充值金额 - 已使用金额（所有结算成本总和）
        BigDecimal result = getDeposit(companyId);
        companySearchOutVo.setDeposit(result);

        return companySearchOutVo;
    }

    private BigDecimal getDeposit(Integer companyId) {
        BigDecimal payAmount = BigDecimal.ZERO;
        BigDecimal totalPayAmount = BigDecimal.ZERO;
        List<SysYszk> sysYfzkList = sysYszkMapper.selectList(Wrappers.<SysYszk>lambdaQuery().eq(SysYszk::getCompanyId
                , companyId));
        // 1.4.1 充值金额
        for (SysYszk sysYfzk : sysYfzkList) {
            totalPayAmount = totalPayAmount.add(sysYfzk.getTotalPayAmount());
        }
        // 1.4.2 已使用金额 = 该渠道商所有订单的商品的结算成本总和
        List<BuyerOrder> buyerOrders =
                buyerOrderMapper.selectList(Wrappers.<BuyerOrder>lambdaQuery().eq(BuyerOrder::getDistributorId,
                        companyId));
        for (BuyerOrder buyerOrder : buyerOrders) {
            if (buyerOrder != null && buyerOrder.getCost() != null && !buyerOrder.getCost().equals(BigDecimal.ZERO)) {
                payAmount = payAmount.add(buyerOrder.getCost());
            }
        }
        // 预存款余额
        return totalPayAmount.subtract(payAmount);
    }

    @Override
    public CompanyCountOutVo getCount() {
        LocalDate yesterday =  LocalDate.now().minusDays(1);
        Integer companyId = TokenService.getUserBytoken().getCompanyId();
        Long onSaleGoods = 0L;
        Long reviewedGoods = 0L;
        BigDecimal usedTrustLimit = BigDecimal.ZERO;
        BigDecimal usedPayAmount = BigDecimal.ZERO;
        BigDecimal margin = BigDecimal.ZERO;
        CompanyCountOutVo companyCountOutVo = new CompanyCountOutVo();
        LambdaQueryWrapper<BuyerOrder> qw = Wrappers.<BuyerOrder>lambdaQuery().eq(BuyerOrder::getDistributorId,
                    companyId);
        Integer count = workOrderInfoMapper.getCountBySaler(companyId);

        // 售后订单
        companyCountOutVo.setAftermarketOrders(String.valueOf(count));

        // 昨日订单数
        Long orderNum = buyerOrderMapper.selectCount(qw.like(BuyerOrder::getPayTime,
                yesterday));
        companyCountOutVo.setYesterdayOrders(String.valueOf(orderNum));

        List<CompanyGoods> companyGoodsList =
                companyGoodsMapper.selectList(Wrappers.<CompanyGoods>lambdaQuery().eq(CompanyGoods::getCompanyId,
                        companyId));
        List<Integer> companyIdList =
                companyGoodsList.stream().map(CompanyGoods::getGoodsId).collect(Collectors.toList());
        for (Integer id : companyIdList) {
            onSaleGoods = goodsInfoMapper.selectCount(Wrappers.<GoodsInfo>lambdaQuery().eq(GoodsInfo::getId,id).eq(GoodsInfo::getStatusSysUp, 1));
        }

        reviewedGoods = goodsInfoMapper.selectCount(Wrappers.<GoodsInfo>lambdaQuery().eq(GoodsInfo::getStatusVerify,
                1));

        // 在售商品数
        companyCountOutVo.setGoodsOnSale(String.valueOf(onSaleGoods));
        // 审核已通过商品数
        companyCountOutVo.setReviewedGoods(String.valueOf(reviewedGoods));

        // TODO:风控预警
        companyCountOutVo.setFkyj("请提供明确公式");

        // 备券批次数量
        Long cardNum = cardsBatch1Mapper.getCardNum(companyId);
        companyCountOutVo.setCardBatchNum(cardNum);

        List<Map<String, Object>> results = cardsBatch1Mapper.getNum(companyId);
        for (Map<String, Object> result : results) {
            // 获取num和type的值
            Long num = (Long) result.get("num");
            String type = (String) result.get("type");
            // 积分卡批次数
            if (type.equals("JFK")) companyCountOutVo.setJfkNum(num);
            // 电影券
            if (type.equals("DYQ")) companyCountOutVo.setDyqNum(num);
            // 礼品卡
            if (type.equals("LPK")) companyCountOutVo.setLpkNum(num);
        }

        List<BuyerOrder> buyerOrders = buyerOrderMapper.selectList(qw);
        for (BuyerOrder buyerOrder : buyerOrders) {
            // 利润额
            if (buyerOrder.getMargin() == null){
                margin = BigDecimal.valueOf(0);
            }else {
                margin = margin.add(buyerOrder.getMargin());
            }
            // 已使用金额
            if (buyerOrder.getCost()==null){
                usedPayAmount = BigDecimal.valueOf(0);
            }else {
                usedPayAmount = usedPayAmount.add(buyerOrder.getCost());
            }

        }

        // 已用授信额度
        List<BuyerOrder> use = buyerOrderMapper.selectList(qw.eq(BuyerOrder::getCardPrice, "usedTrustLimit"));
        for (BuyerOrder card : use) {
            if (card.getCardPrice() != null) {
                usedTrustLimit = usedTrustLimit.add(card.getCardPrice());
            }
        }
        companyCountOutVo.setUsedTrustLimit(usedTrustLimit);

        // 利润额
        companyCountOutVo.setMargin(margin);
        // 已使用金额
        companyCountOutVo.setUsedPayAmount(usedPayAmount);
        // 剩余金额
        BigDecimal deposit = getDeposit(companyId);
        companyCountOutVo.setPayAmount(deposit);

        if (TokenService.getUserBytoken().getSysType().equals("saler")) {
            // 剩余授信额度
            SysYszk sysYszk = sysYszkMapper.selectOne(Wrappers.<SysYszk>lambdaQuery().eq(SysYszk::getCompanyId,
                    companyId));
            companyCountOutVo.setTrustLimit(sysYszk.getTrustLimit());
        }


        return companyCountOutVo;
    }

    @Override
    public SystemSearchOutVo getTodayCountData(SystemSearchInVo inVo) {
        SystemSearchOutVo outVo = new SystemSearchOutVo();
        if (inVo == null) {
            outVo = countAllData();
        } else {
            outVo = countSearchData(inVo);
        }
        return outVo;
    }

    private SystemSearchOutVo countSearchData(SystemSearchInVo inVo) {
        SystemSearchOutVo outVo = new SystemSearchOutVo();
        // 渠道商名称模糊查询
        List<CompanyInfo> companyInfos =
                companyInfoMapper.selectList(Wrappers.<CompanyInfo>lambdaQuery()
                        .like(StrUtil.isNotBlank(inVo.getCompanyName()), CompanyInfo::getCompanyName,
                                inVo.getCompanyName())
                        .ge(inVo.getStartTime() != null, CompanyInfo::getCreateTime, inVo.getStartTime())
                        .le(inVo.getEndTime() != null, CompanyInfo::getCreateTime, inVo.getEndTime())
                );
        if (companyInfos.size() == 0) {
            return outVo;
        }
        for (CompanyInfo companyInfo : companyInfos) {
            if (companyInfo != null && companyInfo.getId() != null && companyInfo.getId() != 0) {
                Integer companyId = companyInfo.getId();
                LambdaQueryWrapper<BuyerOrder> wrapper = Wrappers.<BuyerOrder>lambdaQuery()
                        .eq(BuyerOrder::getDistributorId, companyId)
                        .ge(inVo.getStartTime() != null, BuyerOrder::getCreateTime, inVo.getStartTime())
                        .le(inVo.getEndTime() != null, BuyerOrder::getCreateTime, inVo.getEndTime());
                // 订单数
                Long orderNum = buyerOrderMapper.selectCount(wrapper);
                outVo.setOrderNum(orderNum);
                // 终端用户数
                Long userNum = buyerUserMapper.selectCount(Wrappers.<BuyerUser>lambdaQuery().eq(BuyerUser::getCompanyId,
                                companyId)
                        .ge(inVo.getStartTime() != null, BuyerUser::getCreateTime, inVo.getStartTime())
                        .le(inVo.getEndTime() != null, BuyerUser::getCreateTime, inVo.getEndTime())
                );
                outVo.setUserNum(userNum);
                // 待发货
                Long pendingShipmentNum = buyerOrderMapper.selectCount(wrapper.eq(BuyerOrder::getOrderStatus, 2));
                outVo.setPendingShipmentNum(pendingShipmentNum);
                // 已发货
                Long shipmentNum = buyerOrderMapper.selectCount(wrapper.eq(BuyerOrder::getOrderStatus, 3));
                outVo.setShipmentNum(shipmentNum);
            }
        }
        return outVo;
    }

    private SystemSearchOutVo countAllData() {
        SystemSearchOutVo outVo = new SystemSearchOutVo();
        LambdaQueryWrapper<BuyerOrder> wrapper = Wrappers.<BuyerOrder>lambdaQuery();
        // 订单数
        Long orderNum = buyerOrderMapper.selectCount(null);
        outVo.setOrderNum(orderNum);
        // 终端用户数
        Long userNum = buyerUserMapper.selectCount(null);
        outVo.setUserNum(userNum);
        // 待发货
        Long pendingShipmentNum = buyerOrderMapper.selectCount(wrapper.eq(BuyerOrder::getOrderStatus, 2));
        outVo.setPendingShipmentNum(pendingShipmentNum);
        // 已发货
        Long shipmentNum = buyerOrderMapper.selectCount(wrapper.eq(BuyerOrder::getOrderStatus, 3));
        outVo.setShipmentNum(shipmentNum);
        return outVo;
    }

    @Override
    public SystemSearchOutVo getAllCountData() {
        Integer companyId = TokenService.getUserBytoken().getCompanyId();
        SystemSearchOutVo outVo = countAllData();
        // 渠道商数量
        Long companyNum =
                companyInfoMapper.selectCount(Wrappers.<CompanyInfo>lambdaQuery().eq(CompanyInfo::getIsDistributor, 1));
        outVo.setCompanyNum(companyNum);
        // 供应商数量
        Long venderNum =
                companyInfoMapper.selectCount(Wrappers.<CompanyInfo>lambdaQuery().eq(CompanyInfo::getIsVendor, 1));
        outVo.setVenderNum(venderNum);
        // 风控预警用户
        Long userNum = buyerUserMapper.selectCount(Wrappers.<BuyerUser>lambdaQuery().eq(BuyerUser::getCompanyId,
                companyId).eq(BuyerUser::getIsFk, 1));
        outVo.setFkNum(userNum);
        return outVo;
    }

    @Override
    public ArrayList<String> think(String inVo) {
        return this.baseMapper.think(inVo);
    }

    @Override
    public CompanyCountOutVo getCountByVender() {
        LocalDate yesterday =  LocalDate.now().minusDays(1);
        Integer companyId = TokenService.getUserBytoken().getCompanyId();

        CompanyCountOutVo companyCountOutVo = new CompanyCountOutVo();
        LambdaQueryWrapper<BuyerOrder> qw = Wrappers.<BuyerOrder>lambdaQuery().eq(BuyerOrder::getVendorId,companyId);
        Integer count = workOrderInfoMapper.getCount(companyId);

        // 售后订单
        companyCountOutVo.setAftermarketOrders(String.valueOf(count));

        Long orderNum = buyerOrderMapper.selectCount(qw.like(BuyerOrder::getPayTime,
                yesterday));
        // 昨日订单数
        companyCountOutVo.setYesterdayOrders(String.valueOf(orderNum));

        Long reviewedGoods = goodsInfoMapper.selectCount(Wrappers.<GoodsInfo>lambdaQuery().eq(GoodsInfo::getStatusVerify,
                1));
        // 审核已通过商品数
        companyCountOutVo.setReviewedGoods(String.valueOf(reviewedGoods));
        return companyCountOutVo;
    }
}
